﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows;
using Cognex.VisionPro;
using Cognex.VisionPro.ToolBlock;
using Cognex.VisionPro.FGGigE.Implementation.Internal;
using CogAcqFifoTool = Cognex.VisionPro.CogAcqFifoTool;
using Cognex.VisionPro.PMAlign;
using Cognex.VisionPro.CalibFix;
using Cognex.VisionPro.ImageProcessing;
using HslCommunication.ModBus;
using System.IO;
using Newtonsoft.Json;
using NLog;

namespace Delta
{

    public partial class Form1 : Form
    {
        /// <summary>
        /// 运动控制界面
        /// </summary>
        public MotionForm motionform;
        /// <summary>
        /// VisionPro
        /// </summary>
        public Cog cog;

        /// <summary>
        /// 登录界面
        /// </summary>
        public FormLogin formlogin;

        public VisionSetForm visionSet;
        public Trigger triggerForm;
        public AllParameterCSVForm ParameterCSVForm;
        public LayoutForm layoutForm;
        public LayoutInformation layoutInformation;
        public FormVpToolBlock formVpToolBlock;
        public EIP_PIC PIC;
        public List<int> CombineList = new List<int>();
        public BackgroundWorker[] BackWorkerInspectImage = null;
        public static Logger logger = LogManager.GetCurrentClassLogger();
        public bool SystemOnline = false, IsSaveOKImg = false, IsSaveNGImg = false;
        public List<PointF>[] listPoint;
        public Queue<PointF>[] QueuePoint;
        public int imageCatch;
        public int SettingNum, TotalCatchNum, CurrectCatchNum;
        int foreTrigger = 0;
        public Form1()
        {
            InitializeComponent();
            timerTimer.Start();
            IsFirstInitial = true;
            SubFormLoad();
            rdoBtnOnLine.Checked = true;
            //界面露出任务栏
            this.MaximizedBounds = Screen.PrimaryScreen.WorkingArea;
            //必加，不加也不会实现
            this.WindowState = System.Windows.Forms.FormWindowState.Maximized;
            new AutoFormChange(this);




        }

        /// <summary>
        /// 子窗体初始化
        /// </summary>
        public void SubFormLoad()
        {
            layoutInformation = new LayoutInformation();
            cog = new Cog(this);
            motionform = new MotionForm(this);
            formlogin = new FormLogin(this);
            visionSet = new VisionSetForm(this);
            triggerForm = new Trigger(this);
            ParameterCSVForm = new AllParameterCSVForm(this);
            formVpToolBlock = new FormVpToolBlock(this);
            BackWorkerInspectImage = new BackgroundWorker[1];
            for (int i = 0; i < BackWorkerInspectImage.Length; i++)
            {
                BackWorkerInspectImage[i] = new BackgroundWorker();
                BackWorkerInspectImage[i].DoWork -= new DoWorkEventHandler(ImageToolBlockRun);
                BackWorkerInspectImage[i].DoWork += new DoWorkEventHandler(ImageToolBlockRun);
            }
            PIC = new EIP_PIC();
            QueuePoint = new Queue<PointF>[8];
            listPoint = new List<PointF>[8];
        }

        public bool IsFirstInitial { get; set; }
        /// <summary>
        /// 窗体加载，初始化参数
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_Load(object sender, EventArgs e)
        {
            rdoBtnOnLine.Checked = true;
            rdoBtnOffLine.Checked = false;
            triggerForm.OpenDev_Click(sender, e);
            triggerForm.TriggerMode.Checked=true;
            //Thread.Sleep(100);
            triggerForm.StartPlay_Click(sender, e);
            ParameterCSVForm.dataGridView1.DataSource = ParameterCSVForm.LoadCSVWithCsvHelper(Application.StartupPath + @"\ParameterCSV\Parameter.CSV");
            ReadlayoutInformation(Application.StartupPath + @"\LayoutInformation\3225CF\LayoutInformation.config");
            layoutForm = new LayoutForm(this);
            CombineList = layoutForm.CombineListModel(layoutForm.ListModel, layoutInformation.ProductRows, layoutInformation.ProductCols, layoutInformation.layers);
            SettingNum = CombineList.Count;
            label_SettingNum.Text = "设置数量:" + SettingNum.ToString();
            layoutForm.ProductTypeUsed = layoutInformation.ProductTypeUsed;
            Cog.LoadVpp(formVpToolBlock.DefalutVppPath + layoutInformation.CurrentMaterial + "\\", formVpToolBlock.DefalutVppPath + layoutInformation.CurrentMaterial + "\\", false, Vpptype.myCogToolBlock1);

            timer1.Enabled = true;



        }

        public bool ReadlayoutInformation(string pathFilename)
        {
            if (File.Exists(pathFilename))
            {
                string str = File.ReadAllText(pathFilename);
                layoutInformation = JsonConvert.DeserializeObject<LayoutInformation>(str);
                return true;
            }
            else
            {
                return false;
            }

        }

        public bool WritelayoutInformation(string pathFilename)
        {
            string str = JsonConvert.SerializeObject(layoutInformation, Formatting.Indented);
            File.WriteAllText(pathFilename, str, Encoding.UTF8);
            return true;
        }


        /// <summary>
        /// 用户权限
        /// </summary>
        /// <param name="isLogin"></param>
        public void AdminRight(bool isLogin)
        {
            if (isLogin)
            {

                btnManualExecute.Enabled = true;
                btnVisionSet.Enabled = true;
                btnMotionSet.Enabled = true;
                btnSocketSet.Enabled = true;
                btnSystemSet.Enabled = true;
            }
            else
            {
                btnManualExecute.Enabled = false;
                btnVisionSet.Enabled = false;
                btnMotionSet.Enabled = false;
                btnSocketSet.Enabled = false;
                btnSystemSet.Enabled = false;
            }
        }

        #region 最大最小化窗体
        private void btnMaxOrNormal_Click(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Maximized)
            {
                WindowState = FormWindowState.Normal;
            }
            else
            {
                WindowState = FormWindowState.Maximized;
            }
        }
        private void btnClose_Click(object sender, EventArgs e)
        {
            this.Close();
        }
        private void btnMin_Click(object sender, EventArgs e)
        {
            this.WindowState = FormWindowState.Minimized;
        }
        #endregion

        private void timerTimer_Tick(object sender, EventArgs e)
        {
            DateTime dt = DateTime.Now;
            lblTime.Text = dt.ToString("yyyy-MM-dd  HH:mm:ss");
        }

        private void btnVisionSet_Click(object sender, EventArgs e)
        {
            visionSet.Show();
        }

        private void btnCameraSet_Click(object sender, EventArgs e)
        {

        }

        private void btnSocketSet_Click(object sender, EventArgs e)
        {
            ParameterCSVForm.ShowDialog();
        }

        private void btnSystemSet_Click(object sender, EventArgs e)
        {
            //PIC.ReadSingleTag("protocol = INOVANCE & gateway = 192.168.0.11 & path = 0, 1 & cpu = AM521 & name = IO变量.输入");

            layoutForm.ShowDialog();
        }

        /// <summary>
        /// 登录按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnLoginSet_Click(object sender, EventArgs e)
        {
            if (formlogin.IsDisposed)
            {
                formlogin = new FormLogin(this);
            }
            formlogin.ShowDialog();
        }

        private void btnCalibtSet_Click(object sender, EventArgs e)
        {

        }

        private void btnOnceCamera_Click(object sender, EventArgs e)
        {

        }



        private void btnManualRun_Click(object sender, EventArgs e)
        {


        }


        private void rdoBtnOnLine_CheckedChanged(object sender, EventArgs e)
        {
            if (rdoBtnOnLine.Checked == true)
            {
                rdoBtnOffLine.Checked = false;

                btnManualExecute.Enabled = false;
                btnVisionSet.Enabled = false;
                btnMotionSet.Enabled = false;
                btnSocketSet.Enabled = false;
                btnSystemSet.Enabled = false;
                btnLoginSet.Enabled = false;


            }

        }

        private void rdoBtnOffLine_CheckedChanged(object sender, EventArgs e)
        {
            if (rdoBtnOffLine.Checked == true)
            {
                rdoBtnOnLine.Checked = false;
                btnLoginSet.Enabled = true;
                timer1.Enabled = false;
            }

            else
            {
                rdoBtnOnLine.Checked = true;
                btnLoginSet.Enabled = false;
                timer1.Enabled = true;
            }

        }


        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
        }


        private void btnOpenImg_Click(object sender, EventArgs e)
        {

        }






        private void tableLayoutPanel2_Paint(object sender, PaintEventArgs e)
        {

        }


        private void btnHome_Paint(object sender, PaintEventArgs e)
        {

        }

        private void btnMotionSet_Click(object sender, EventArgs e)
        {
            motionform.Show();
        }

        private void btnManualExecute_Click(object sender, EventArgs e)
        {
            triggerForm.SoftTriggerFire_Click(sender, e);

        }

       

        public void ImageToolBlockRun(object sender, DoWorkEventArgs e)
        {
            try
            {
                SnapInfo info = (SnapInfo)e.Argument;
                imageCatch = 0;
                label_CurrectXY.Text = "";
                if (info.Image != null)
                {
                    cogRecordDisplay1.Image = new CogImage8Grey(info.Image);
                    
                    Invoke(new Action(() => {
                        Cog.myCogToolBlock1.Inputs["Image"].Value = new CogImage8Grey(info.Image);
                        Cog.myCogToolBlock1.Inputs["ToolEnable"].Value = layoutForm.ProductTypeUsed;
                        Cog.myCogToolBlock1.Run();
                    }));
                    cogRecordDisplay1.Record = Cog.myCogToolBlock1.CreateCurrentRecord();
                    cogRecordDisplay1.Fit(true);

                    if (Cog.myCogToolBlock1.RunStatus.Result != CogToolResultConstants.Error)
             {                       
                    Cognex.VisionPro.Blob.CogBlobResultCollection ResultBlobs = Cog.myCogToolBlock1.Outputs["BlobResultCollection"].Value as Cognex.VisionPro.Blob.CogBlobResultCollection;
              if (ResultBlobs!=null)
                {
                      
                      int BlobArea_Max =(int) Cog.myCogToolBlock1.Inputs["BlobArea_Max"].Value;

                    if (!(bool)Cog.myCogToolBlock1.Inputs["EnoughMaterial"].Value)//缺料发送信号给PLC
                    {


                        return;
                    }
                    foreach (Cognex.VisionPro.Blob.CogBlobResult blob in ResultBlobs)
                    {
                        // 获取斑点属性
                        double area = blob.Area; // 面积(像素)
                        double centerX = blob.CenterOfMassX; // 质心X坐标
                        double centerY = blob.CenterOfMassY; // 质心Y坐标
                        if (area> BlobArea_Max)//有物料聚集发送信号给PLC
                        {




                            return;
                        }
                    }
                       
                        QueuePoint = new Queue<PointF>[8];
                    listPoint =  new List<PointF>[8];

                    for (int i = 0; i < layoutForm.ProductTypeUsed.Length; i++)
                    {
                        if (layoutForm.ProductTypeUsed[i])
                        {
                            if (Cog.myCogToolBlock1.Outputs[$"Point{i + 1}"].Value!=null)
                            {
                                listPoint[i] = (List<PointF>)Cog.myCogToolBlock1.Outputs[$"Point{i + 1}"].Value;
                                imageCatch = imageCatch + listPoint[i].Count;
                                foreach (PointF item in listPoint[i])
                                {
                                    QueuePoint[i].Enqueue(item);
                                }
                            }   
                        }
                    }
                    if (imageCatch > 0)
                    {
                        DataGridViewShowCoordinates(imageCatch, CurrectCatchNum);//拍照完成后刷新显示
                    }
                   
                }

                }
            }
            }
            catch (Exception ex)
            {
                logger.Error(ex.ToString());
            }

        }
        private void btn_ResetCount_Click(object sender, EventArgs e)
        {          
            CurrectCatchNum = 0;
            TotalCatchNum = 0;
        }
        private void timer1_Tick(object sender, EventArgs e)
        {
            int curTrigger;
            if (SystemOnline)
            {
                //IO.Write_SingleIO(int.Parse(data.IOOnline), IO.State.ON);  //联机信号
                if (true)//触发信号
                {//接受相机拍照信号
                    curTrigger = 1;
                }
                else
                {
                    curTrigger = 0;
                }
                if (curTrigger - foreTrigger == 1)
                {
                    triggerForm.SoftTriggerFire_Click(sender, e);//拍照
                }
                foreTrigger = curTrigger;
            }





            if (true)//判断是否吸取成功
            {
                CurrectCatchNum++;
                TotalCatchNum++;

                PointF point = new PointF();
                point = SetPLCCoordinates(CurrectCatchNum);//队列中取值，坐标发送给PLC
               
            }

            //if (QueuePoint[CombineList[CurrectCatchNum]].Count==0)//需要抓取的产品队列为空，发送信号给PLC
            //{

            //}

            if (imageCatch==0)//抓取完了，需要发送信号给PLC重新拍照。
            {
                
            }
            if (CurrectCatchNum == CombineList.Count)//全部抓取完成
            {
                CurrectCatchNum = 0;

            }

            if (true)//收到PLC信号，总抓取数量复位
            {
                TotalCatchNum = 0;
            }


            label_CurrectCatchNum.Text = "当前抓取数量:" + CurrectCatchNum.ToString();
            label_TotalCatchNum.Text = "总抓取数量:"+ TotalCatchNum.ToString();

        }

        public PointF SetPLCCoordinates(int HaveFixedProductNum)
        {
            PointF point = new PointF();
            point.X = 0;
            point.Y = 0;
            if (layoutForm.ProductTypeUsed[CombineList[HaveFixedProductNum]] && QueuePoint!=null)//模板类型是否启用
            {
                if (QueuePoint[CombineList[HaveFixedProductNum]].Count > 0)
                {
                    point = QueuePoint[CombineList[HaveFixedProductNum]].Dequeue();//对应的模板数组里取出数据
                    label_CurrectXY.Text = "当前坐标： " + point.X.ToString() + ";" + point.Y.ToString();
                    return point;
                }
                else
                {
                    return point;
                }
                //listPoint = new List<PointF>[8];
                //foreach (PointF item in QueuePoint[CombineList[HaveFixedProductNum]])//取走后重新把队列数据放回到list
                //{
                //    listPoint[CombineList[HaveFixedProductNum]].Add(item);

                //}

               
            }

            else
            {
                return point;
            }

        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="QueuePoint"></param>
        /// <param name="CatchCount">拍照取到数量</param>
        /// <param name="HaveFixedProductNum">固定模板数组中的序号</param>
        public void DataGridViewShowCoordinates(int imageCatch, int ProductNum)
        {
            for (int i = 0; i < imageCatch; i++)
            {
                Dgv_DataShow.Rows[i].Cells["序号"].Value = i + 1;
                Dgv_DataShow.Rows[i].Cells["X"].Value = listPoint[CombineList[ProductNum]][i].X;
                Dgv_DataShow.Rows[i].Cells["Y"].Value = listPoint[CombineList[ProductNum]][i].Y;
                Dgv_DataShow.Rows[i].Cells["模板"].Value = CombineList[ProductNum];
            }


        }

    }
}
